home *** CD-ROM | disk | FTP | other *** search
- From: adrian@milton.u.washington.edu (Adrian Mariano)
- Newsgroups: comp.sources.misc
- Subject: v19i012: plot3d - plot 3d surfaces as wire meshes, Part01/01
- Message-ID: <1991May2.154945.7871@sparky.IMD.Sterling.COM>
- Date: 2 May 91 15:49:45 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 119521c3 90b22bc4 5ca00479 ccdafc27
-
- Submitted-by: Adrian Mariano <adrian@milton.u.washington.edu>
- Posting-number: Volume 19, Issue 12
- Archive-name: plot3d/part01
-
- This program plots 3d surfaces as wire meshes. It supports cartesian,
- cylindrical and spherical coordinates. This version compiles under
- MSDOS with Turbo C. It shouldn't be very difficult to port to other
- environments, however.
-
- Adrian Mariano
- ----------
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # calc.c
- # graph.c
- # makefile
- # plot.c
- # plot3d.c
- # plot3d.h
- # readme
- # This archive created: Tue Apr 30 14:21:27 1991
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'calc.c'
- then
- echo shar: "will not over-write existing file 'calc.c'"
- else
- cat << \SHAR_EOF > 'calc.c'
- /*
-
- Plot3d -- calc.c, the function evaluation code
-
- By Karl Crary -- kc2m+@andrew.cmu.edu
-
-
- Copyright (c) 1991 by Karl Crary
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- */
-
-
- #include "plot3d.h"
-
- int convert(char string[],char **errormsg,char stackno); /* convert infix to RPN in fstack */
- void process(char operator,unsigned char *findex,char cstack[],char *cstacktop,term fstack[]);
- char precedence(char operator, char push);
- void simplify(char stackno);
- double gamma(double arg);
-
- extern char stop;
- char ferr;
-
- double ff(double arg1, double arg2, char stackno)
- {
- static unsigned char begin = 0;
- long double stack[25], intermediate;
- unsigned char findex;
- char height, ii, recurse;
- if ((arg1 < -MAXDOUBLE) || (arg1 > MAXDOUBLE)) {
- ferr = 1;
- return(0);
- }
- if (range(-MINDOUBLE,arg1,MINDOUBLE)) arg1 = 0;
- ferr = 0;
- height = recurse = 0;
- if (begin) recurse = 1;
-
- for ((findex = begin),(begin = 0); fstack[stackno][findex].operator != '='; findex++) {
- if (!stop && kbhit()) {
- ii = getch();
- if (ii == ' ') stop = 2;
- if (ii == 24) terminate();
- if (ii == 27) {
- stop = 1;
- return(0);
- }
- }
- switch (fstack[stackno][findex].operator) {
- case '#' :
- if (height >= 25) {
- ferr = 1;
- break;
- }
- for (ii = height; ii > 0; ii--) stack[ii] = stack[ii-1];
- height++;
- stack[0] = fstack[stackno][findex].operand;
- break;
- case 'y' :
- if (height >= 25) {
- ferr = 1;
- break;
- }
- for (ii = height; ii > 0; ii--) stack[ii] = stack[ii-1];
- height++;
- stack[0] = arg2;
- break;
-
- case 'x' :
- if (height >= 25) {
- ferr = 1;
- break;
- }
- for (ii = height; ii > 0; ii--) stack[ii] = stack[ii-1];
- height++;
- stack[0] = arg1;
- break;
- case '^' :
- if (((stack[1] == 0) && (stack[0] <= 0)) || ((stack[1] < 0) && (stack[0] != floor(stack[0])))) ferr = 1;
- else intermediate = pow(stack[1],stack[0]);
- if (intermediate == HUGE_VAL) ferr = 1;
- else stack[0] = intermediate;
- goto popstack;
- case '\\' : /* root */
- if ((stack[0] == 0) && (stack[1] <= 0)) ferr = 1; /* division by zero */
- if (stack[1] == 0) ferr = 1; /* zeroth root */
- if ((stack[0] < 0) && (floor((stack[1]+1)/2) != (stack[1]+1)/2)) ferr = 1;
- if (!ferr) stack[0] = (stack[0] < 0 ? -1 : 1)*pow(fabs(stack[0]),1/stack[1]);
- goto popstack;
- case '*' :
- stack[0] = stack[0] * stack[1];
- goto popstack;
- case '/' :
- if (stack[0] == 0) ferr = 1;
- else stack[0] = stack[1] / stack[0];
- goto popstack;
- case '+' :
- stack[0] = stack[0] + stack[1];
- goto popstack;
- case '-' :
- stack[0] = stack[1] - stack[0];
- goto popstack;
- case 'm' :
- stack[0] = -stack[0];
- break;
- case 's' :
- stack[0] = sin(stack[0]);
- break;
- case 'c' :
- stack[0] = cos(stack[0]);
- break;
- case 't' :
- stack[0] = tan(stack[0]);
- break;
- case 'S' :
- if (!range(-1,stack[0],1)) ferr = 1;
- else stack[0] = asin(stack[0]);
- break;
- case 'C' :
- if (!range(-1,stack[0],1)) ferr = 1;
- else stack[0] = acos(stack[0]);
- break;
- case 'T' :
- stack[0] = atan(stack[0]);
- break;
- case 1 : /* sinh */
- stack[0] = sinh(stack[0]);
- break;
- case 2 : /* cosh */
- stack[0] = cosh(stack[0]);
- break;
- case 3 : /* tanh */
- stack[0] = tanh(stack[0]);
- break;
- case 4 : /* invsinh */
- stack[0] = log(stack[0] + sqrt(pow(stack[0],2) + 1));
- break;
- case 5 : /* invcosh */
- intermediate = pow(stack[0],2);
- if (intermediate < 1) ferr = 1;
- else {
- intermediate = stack[0] + sqrt(intermediate - 1);
- if (intermediate <= 0) ferr = 1;
- else stack[0] = log(stack[0] + sqrt(pow(stack[0],2) - 1));
- }
- break;
- case 6 : /* invtanh */
- if (stack[0] == 1) ferr = 1;
- else {
- intermediate = (1 + stack[0])/(1 - stack[0]);
- if (intermediate <= 0) ferr = 1;
- else stack[0] = log(intermediate)/2;
- }
- break;
- case 'l' :
- if (stack[0] <= 0) ferr = 1;
- else stack[0] = log10(stack[0]);
- break;
- case 'n' :
- if (stack[0] <= 0) ferr = 1;
- else stack[0] = log(stack[0]);
- break;
- case 'a' : /* absolute value */
- stack[0] = fabs(stack[0]);
- break;
- case 'g' : /* gamma */
- stack[0] = gamma(stack[0]);
- break;
- case 'f' : /* user function */
- stack[0] = ff(stack[0],0,1);
- break;
- popstack:
- height--;
- for (ii = 1; ii < height; ii++) stack[ii] = stack[ii+1];
- break;
- }
- if ((stack[0] < -2 * MAXDOUBLE) || (stack[0] > 2 * MAXDOUBLE)) ferr = 1; /* roundoff makes MAXDOUBLE > MAXDOUBLE */
- if (ferr) return(0);
- }
- if (recurse) begin = findex; /* return where ended */
- return(stack[0]);
- }
-
-
-
- int matherr(struct exception *e)
- {
- ferr = 1;
- return(1);
- }
-
-
-
- double gamma(double arg)
- {
- double xx, total;
- char ii;
- /* magic gamma generating coefficients */
- static double coef[7] = { 0.988205891,-0.897056937, 0.918206857,
- -0.756704078, 0.482199394,-0.193527818,
- 0.035868343};
-
- if (!stop && kbhit()) {
- ii = getch();
- if (ii == ' ') stop = 2;
- if (ii == 24) terminate();
- if (ii == 27) {
- stop = 1;
- return(0);
- }
- }
- if (arg <= 0) {
- if (arg == floor(arg)) {
- ferr = 1;
- return(0);
- }
- else {
- arg = -arg + 1; /* recurse if x < 0 */
- return(M_PI/(gamma(arg)*sin(M_PI*arg)));
- }
- }
- else if (arg < 1) return(gamma(arg+1)/arg); /* recurse if x < 1 */
- else if (arg <= 2) {
- arg--;
- total = 1 - 0.577191652 * arg;
- xx = arg;
- for (ii = 0; ii <= 6; ii++) {
- xx *= arg;
- total += coef[ii] * xx;
- }
- return(total);
- }
- else { /* arg > 2 */
- xx = arg * arg; /* another approximation for larger x */
- total = (arg - 0.5) * log(arg);
- total -= arg;
- total += log(2 * M_PI) / 2;
- total += 1 / (12 * arg);
- total -= 1 / (360 * arg * xx);
- total += 1 / (1260 * arg * xx * xx);
- total -= arg / (1680 * xx * xx * xx * xx);
- return(exp(total));
- }
- }
-
-
-
-
-
- /* errormessages */
- char errorlist[6][45] = {"Values must precede each binary operator.",\
- "Unmatched right parenthesis.",\
- "Expression must end with value.",\
- "Stack overflow.",\
- "Function ends in operator.",\
- "Unbalanced parentheses."};
-
-
-
- int convert(char string[], char **errormsg, char stackno)
- {
- unsigned char findex;
- char *cursor, value, inverse;
- char cstack[100], cstacktop;
- #define PROCESS(operator) process((operator),&findex,cstack,&cstacktop,fstack[stackno])
-
- cursor = string;
- findex = value = inverse = 0;
- cstack[0] = '('; /* initialize cstack */
- cstacktop = 0;
- while (*cursor != 0) {
- switch (*cursor) {
- case '=' : /* explicit definition */
- cursor++;
- findex = value = inverse = 0; /* discard everything and start over */
- cstack[0] = '(';
- cstacktop = 0;
- break;
- case 'h' : /* hyperbolics already taken care of */
- cursor++;
- break;
- case '0' : /* numbers */
- case '1' :
- case '2' :
- case '3' :
- case '4' :
- case '5' :
- case '6' :
- case '7' :
- case '8' :
- case '9' :
- case '.' :
- if (value) PROCESS('$'); /* process implicit multiplication */
- fstack[stackno][findex].operator = '#'; /* term is a number */
- fstack[stackno][findex].operand = strtod(cursor,&cursor); /* store number */
- findex++;
- value = 1;
- break;
- case 'x' : /* variables */
- case 'y' :
- case 'o' : /* theta */
- case 'r' :
- case 'u' :
- case 'p' : /* pi */
- case 'e' : /* e */
- case '!' : /* infinity */
- if (value) PROCESS('$');
- switch (*cursor) {
- case 'p' :
- fstack[stackno][findex].operator = '#';
- fstack[stackno][findex].operand = M_PI;
- break;
- case 'e' :
- fstack[stackno][findex].operator = '#';
- fstack[stackno][findex].operand = M_E;
- break;
- case '!' :
- fstack[stackno][findex].operator = '#';
- fstack[stackno][findex].operand = MAXDOUBLE;
- break;
- case 'y' :
- fstack[stackno][findex].operator = 'y';
- break;
- default : /* variables */
- fstack[stackno][findex].operator = 'x';
- break;
- }
- findex++;
- cursor++;
- value = 1;
- break;
- case '^' : /* operators */
- case '\\' :
- case '*' :
- case '/' :
- case '+' :
- case '-' :
- if (!value) { /* process unary operators */
- if (*cursor == '+') { /* unary plus, do nothing */
- cursor++;
- break;
- }
- else if (*cursor == '-') { /* unary minus */
- PROCESS('m');
- cursor++;
- break;
- }
- if (errormsg != NULL) (*errormsg) = errorlist[0];
- return(cursor-string); /* return location of error */
- }
- PROCESS(*cursor); /* process operator */
- cursor++;
- value = 0;
- break;
- case '(' :
- if (value) PROCESS('$'); /* process implicit multiplication */
- PROCESS('('); /* process paren */
- cursor++;
- value = 0;
- break;
- case ')' :
- if (!value) { /* expression ends in operator */
- if (errormsg != NULL) *errormsg = errorlist[2];
- return(cursor-string);
- }
- PROCESS(')');
- cstacktop--; /* zap open paren */
- if (cstacktop < 0) {
- if (errormsg != NULL) (*errormsg) = errorlist[1];
- return(cursor-string); /* unbalanced parens */
- }
- cursor++;
- value = 1;
- break;
- case 'd' :
- if (value) PROCESS('$'); /* process implicit multiplication */
- fstack[stackno][findex].operator = 'd'; /* mark start of derivative */
- findex++;
- PROCESS('='); /* process end of derivative */
- cursor++; /* will be followed by parenthesis */
- value = 0;
- break;
- case 'A' :
- cursor++;
- /* inverse of non-trig prevented in IO */
- inverse = 32;
- case 's' :
- case 'c' :
- case 't' :
- if (value) PROCESS('$'); /* process implicit multiplication */
- if (cursor[1] != 'h') PROCESS(*cursor - inverse); /* inverse is lowercase */
- else switch (*cursor) {
- case 's' :
- PROCESS(inverse ? 4 : 1);
- break;
- case 'c' :
- PROCESS(inverse ? 5 : 2);
- break;
- case 't' :
- PROCESS(inverse ? 6 : 3);
- break;
- } /* advance cursor on next pass */
- cursor++;
- value = inverse = 0;
- break;
- case ' ' :
- cursor++;
- break;
- default : /* functions */
- if (value) PROCESS('$'); /* process implicit multiplication */
- PROCESS(*cursor);
- cursor++;
- value = 0;
- break;
- }
- if ((cstacktop >= 100) || (findex >= 99)) {
- if (errormsg != NULL) *errormsg = errorlist[3];
- return(cursor-string); /* stack overflow */
- }
- }
- if (!value) {
- if (errormsg != NULL) *errormsg = errorlist[4];
- return(cursor-1-string); /* function ends with operator, return location error */
- }
- PROCESS(')'); /* flush conversion stack */
- if (cstacktop != 0) { /* unbalanced parens */
- if (errormsg != NULL) *errormsg = errorlist[5];
- return(cursor-string);
- }
- if (findex >= 99) {
- if (errormsg != NULL) *errormsg = errorlist[3];
- return(cursor-string); /* stack overflow or unbalanced parens */
- }
- fstack[stackno][findex].operator = '=';
- return(-1);
- }
-
- void process(char operator,unsigned char *findex,char cstack[],char *cstacktop,term fstack[])
- {
- char pushprec;
- pushprec = precedence(operator,1);
- while (precedence(cstack[*cstacktop],0) >= pushprec) {
- if (cstack[*cstacktop] == '$') cstack[*cstacktop] = '*';
- fstack[*findex].operator = cstack[*cstacktop];
- if (++(*findex) >= 99) break; /* stack overflow */
- (*cstacktop)--;
- }
- if ((operator != ')') && (*cstacktop < 99)) {
- (*cstacktop)++;
- cstack[*cstacktop] = operator;
- }
- }
-
- char precedence(char operator, char push)
- {
- switch (operator) {
- case '(' :
- return(push ? 10 : 0);
- case ')' :
- return(1);
- case '=' : /* end of derivative */
- return(9);
- case '$' : /* implicit multiplication */
- return(6);
- case '\\' :
- case '^' :
- return(push ? 7 : 5);
- case '*' :
- case '/' :
- return(3);
- case '+' :
- case '-' :
- return(2);
- default : /* functions */
- return(push ? 8 : 4);
- }
- }
-
- void simplify(char stackno)
- {
- int ii, jj, restart;
- char last, prevlast;
- restart = -1;
- last = prevlast = 0;
- for (ii = 0; fstack[stackno][ii].operator != '='; ii++) switch (fstack[stackno][ii].operator) {
- case '+' : /* binary operators */
- case '-' :
- case '/' :
- case '*' :
- case '\\' :
- case '^' :
- if (restart == ii - 1) {
- restart = ii;
- break;
- }
- if (last && prevlast) {
- /* load auxiliary function to calculate simplified value */
- fstack[maxffs][0].operator = fstack[stackno][ii-2].operator; /* might not be # */
- fstack[maxffs][0].operand = fstack[stackno][ii-2].operand;
- fstack[maxffs][1].operator = fstack[stackno][ii-1].operator; /* might not be # */
- fstack[maxffs][1].operand = fstack[stackno][ii-1].operand;
- fstack[maxffs][2].operator = fstack[stackno][ii].operator;
- fstack[maxffs][3].operator = '=';
- /* simplify stack */
- ii -= 2; /* update stack position */
- fstack[stackno][ii].operand = ff(0,0,maxffs); /* calculate new value */
- fstack[stackno][ii].operator = '#';
- for (jj = ii+1; fstack[stackno][jj+1].operator != '='; jj++) { /* shift stack left by 2 */
- fstack[stackno][jj].operator = fstack[stackno][jj+2].operator;
- fstack[stackno][jj].operand = fstack[stackno][jj+2].operand;
- }
- last = prevlast = 0;
- ii = restart; /* restart */
- continue;
- }
- else last = 0; /* prevlast irrelevant */
- break;
- case '#' :
- case 'p' :
- case 'e' :
- case '!' :
- prevlast = last;
- last = 1;
- break;
- case 'x' :
- case 'y' :
- restart = ii; /* no need to restart before unsimplifyable character */
- last = 0; /* prevlast irrelevant */
- break;
- case 'm' :
- if (fstack[stackno][ii-1].operator == 'm') { /* nuke double negate */
- for (jj = ii-1; fstack[stackno][jj+1].operator != '='; jj++) { /* shift stack left by 2 */
- fstack[stackno][jj].operator = fstack[stackno][jj+2].operator;
- fstack[stackno][jj].operand = fstack[stackno][jj+2].operand;
- }
- last = prevlast = 0;
- ii = restart;
- continue;
- }
- /* no break */
- default : /* unary operators */
- if (restart == ii - 1) {
- restart = ii;
- break;
- }
- if (last) {
- /* load auxiliary function to calculate simplified value */
- fstack[maxffs][0].operator = fstack[stackno][ii-1].operator; /* might not be # */
- fstack[maxffs][0].operand = fstack[stackno][ii-1].operand;
- fstack[maxffs][1].operator = fstack[stackno][ii].operator;
- fstack[maxffs][2].operator = '=';
- /* simplify stack */
- ii -= 1; /* update stack position */
- fstack[stackno][ii].operand = ff(0,0,maxffs); /* calculate new value */
- fstack[stackno][ii].operator = '#';
- for (jj = ii+1; fstack[stackno][jj].operator != '='; jj++) { /* shift stack left */
- fstack[stackno][jj].operator = fstack[stackno][jj+1].operator;
- fstack[stackno][jj].operand = fstack[stackno][jj+1].operand;
- }
- last = prevlast = 0;
- ii = restart; /* restart */
- continue;
- }
- else last = 0; /* prevlast irrelevant */
- break;
- }
- }
- SHAR_EOF
- fi
- if test -f 'graph.c'
- then
- echo shar: "will not over-write existing file 'graph.c'"
- else
- cat << \SHAR_EOF > 'graph.c'
- /*
-
- Plot3d -- graph.c, the graphics code
-
- By Adrian Mariano -- adrian@milton.u.washington.edu
-
-
- Copyright (c) 1991 by Adrian Mariano
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- */
-
-
- #include <graphics.h>
- #include <conio.h>
- #include <dos.h>
-
-
- int returnmode, maxx, maxy, mode;
-
- /* This function should return to text mode from graphics mode */
-
- void backtotext()
- {
- restorecrtmode();
- textmode(returnmode);
- }
-
-
- /* Enter graphics mode from text mode */
-
- void entergraphics()
- {
- setgraphmode(mode);
- cleardevice();
- setfillstyle(1, 0); /* Sections will be black filled */
- }
-
-
- /* Do graphics initialization, including setting maxx and maxy to the
- maximum x and y values */
-
- void initgraphics()
- {
- int mm, driver = DETECT;
- char *path;
- struct text_info ti;
- gettextinfo(&ti);
- if (ti.screenheight == 50 || ti.screenheight == 43)
- returnmode = C4350;
- else
- returnmode = C80;
- path = "";
- detectgraph((int far *) (&driver), (int far *) (&mode));
- initgraph((int far *) (&driver), (int far *) (&mode), (char far *) (path));
- if ((mm = graphresult()) != grOk) {
- printf("Error: %d\n", mm);
- exit(0);
- }
- maxx = getmaxx();
- maxy = getmaxy();
- backtotext();
- }
-
-
- /* Draw the quadrilateral specified by the four coordinate pairs, filled
- in with a different color than the boundaries are drawn in */
-
- #pragma argsused
-
- void fill(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
- {
- fillpoly(4, MK_FP(_SS, &x1));
- }
-
- /* Draw a line */
-
- void drawline(int x1, int x2, int x3, int x4)
- {
- line(x1, x2, x3, x4);
- }
- SHAR_EOF
- fi
- if test -f 'makefile'
- then
- echo shar: "will not over-write existing file 'makefile'"
- else
- cat << \SHAR_EOF > 'makefile'
- # Makefile for Turbo C++ 1.0
- # Place your library directory below
-
- LIB=c:\prog\c\lib
-
- plot3d.exe: plot.obj calc.obj plot3d.obj graph.obj
- tlink /c /x $(LIB)\c0h plot3d plot calc graph,plot3d,,\
- $(LIB)\graphics $(LIB)\emu $(LIB)\mathh $(LIB)\ch
-
- .c.obj:
- bcc -mh -c -G $*.c
-
-
-
- SHAR_EOF
- fi
- if test -f 'plot.c'
- then
- echo shar: "will not over-write existing file 'plot.c'"
- else
- cat << \SHAR_EOF > 'plot.c'
- /*
-
- Plot3d -- plot.c, the plotting code
-
- By Adrian Mariano -- adrian@milton.u.washington.edu
-
-
- Copyright (c) 1991 by Adrian Mariano
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- */
-
-
- #include "plot3d.h"
-
- /******************************************************************/
- /* */
- /* Parameters to plot3d() */
-
- float xmin=-3; /* Dimensions of display area */
- float xmax=3;
- float ymin=-3;
- float ymax=3;
- float zmin=-3;
- float zmax=3;
-
- float aspect=1.0; /* Aspect ratio */
- float distance=3; /* Perspective distance */
- float tip=-30.0; /* Rotation around y axis */
- float spin=0.0; /* Rotation around z axis */
-
- float var1start;
- float var2start;
- float var1end;
- float var2end;
-
- long var1stepcount=30; /* Number of steps over var 1 */
- long var2stepcount=30; /* Number of steps over var 2 */
-
- /* */
- /******************************************************************/
-
- #define TRUE 1
- #define FRONT 1
- #define FALSE 0
- #define BACK 0
- #define PI 3.14159265
-
-
- /*************************************
- Internal variables
- Global for convenience
- *************************************/
-
- struct sectiontype {
- int x1,y1,x2,y2,x3,y3,x4,y4;
- float x;
- /* char ferr;*/
- };
-
- float xrange,yrange,zrange,sinspin,cosspin,sintip,costip;
- float multx,multy,addx,addy;
-
-
- /* The main function */
- int plot3d(void (*transform)(float *,float *,float *,float,float,float));
-
- /* Takes (x,y,z) and returns (x,y,z) in screen coordinates */
- void realscale(float *xx,float *yy,float *zz);
-
- /* Compare to sections -- used by qsort */
- int sectioncmp(struct sectiontype *a,struct sectiontype *b);
-
- /* plots the data contained the section */
- void plotsections(struct sectiontype *section,int count);
-
- /* Get screen coordinates from float (x,y,z) */
- void scale(int *xint,int *yint,float x,float y,float z);
-
- /* Draw 3d line */
- void line3d(float a,float b,float c,float d,float e,float f);
-
- /* Initialize multx, multy, addx, and addy for use in scaling */
- void calcscale(float xmin,float ymin,float zmin,float xmax,float ymax,float zmax);
-
- /* Draw the axes */
- void drawaxes(char flag);
-
- /* Is this face (of the cube) visible ? */
- int visible(int i);
-
-
-
- /* Function to be plotted */
-
- #define FIX(flag,min,max) ( flag==1 ? max : min )
- #define round(x) floor((x)+0.5)
-
- typedef int(*function)(const void *,const void *);
-
- int plot3d(void (*transform)(float *,float *,float *,float,float,float)) /* transform points to transform to cartesian */
-
- {
- int i,edgecount,steps,steps2; /* Counters */
- float x,y,z; /* Cartesian coordinates */
- float var1step,var2step,var1,var2; /* Values for independent vars */
- struct sectiontype *section; /* Table of sections */
-
-
- /* Get some memory */
- section=farcalloc(var1stepcount+var2stepcount+3+(var1stepcount+1)*(var2stepcount+1),sizeof(struct sectiontype));
- if (!section){
- printf("Insufficient memory\n\n");
- return 0;
- }
- xrange=xmax-xmin; /* Calculate widths for x, y, and z */
- yrange=ymax-ymin;
- zrange=zmax-zmin;
- costip=cos(tip*PI/180); /* Precalculate trig functions for angles */
- sintip=sin(tip*PI/180);
- sinspin=sin(spin*PI/180);
- cosspin=cos(spin*PI/180);
- calcscale(xmin,ymin,zmin,xmax,ymax,zmax); /* Calculate scaling factors */
- var1step=(var1end-var1start)/(var1stepcount);/* Set stepsizes for the */
- var2step=(var2end-var2start)/(var2stepcount);/* independent variables */
- i=0;
- edgecount=0;
- var1=var1start; /* Initialize var1 */
-
- /* First make a partial table of needed boundary values. These are given */
- /* very large x distances so that they will get sorted to the end of the */
- /* section list. A second counter, 'edgecount' is kept. When the */
- /* sections are plotted, the this value will be subtracted from the */
- /* total counter so these edge sections won't be plotted */
-
- /* Create a table of the edge values along the "top" of the function */
- for(var2=var2start,steps=var2stepcount+1; steps ;steps--, i++,edgecount++,var2+=var2step) {
- (*transform)(&x,&y,&z,ff(var1,var2-var2step,0),var1,var2-var2step);
- realscale(&x,&y,&z);
- (section+i)->x4=round(addx+multx*x); /* Bottom left point */
- (section+i)->y4=round(addy+multy*y);
- (section+i)->x=1e37; /* This section will get sorted to the end */
-
- (*transform)(&x,&y,&z,ff(var1,var2,0),var1,var2);
- realscale(&x,&y,&z);
- (section+i)->x3=round(addx+multx*x); /* Bottom right point */
- (section+i)->y3=round(addy+multy*y);
- }
-
- /* Main loop, cycles through var 1 */
- for (var1=var1start+var1step,steps2=var1stepcount; steps2 ;steps2--, var1+=var1step) {
-
- /* Calculate value for left edge of function */
- var2=var2start;
- (*transform)(&x,&y,&z,ff(var1,var2 ,0),var1,var2);
- realscale(&x,&y,&z);
- (section+i)->x3=round(addx+multx*x); /* Bottom right point */
- (section+i)->y3=round(addy+multy*y);
- (section+i)->x=1e37; /* Will get sorted to the end */
- (*transform)(&x,&y,&z,ff(var1-var1step,var2,0),var1-var1step,var2);
- realscale(&x,&y,&z);
- (section+i)->x2=round(addx+multx*x); /* Top right point */
- (section+i)->y2=round(addy+multy*y);
- edgecount++;
- i++;
-
- /* Main loop. Calculate sections for one cycle of var 2 */
- for(var2=var2start+var2step,steps=var2stepcount; steps ; i++ , steps--, var2+=var2step) {
- (*transform)(&x,&y,&z,ff(var1,var2,0),var1,var2);
- realscale(&x,&y,&z);
- (section+i)->x3=round(addx+multx*x); /* Bottom right point */
- (section+i)->y3=round(addy+multy*y);
- (section+i)->x=z;
-
- /* These points have already been calculated */
- (section+i)->x4=(section+i-1)->x3; /* Bottom left point */
- (section+i)->y4=(section+i-1)->y3;
-
- (section+i)->x2=(section+i-var2stepcount-1)->x3; /* Top right */
- (section+i)->y2=(section+i-var2stepcount-1)->y3;
-
- (section+i)->x1=(section+i-var2stepcount-1)->x4; /* Top left */
- (section+i)->y1=(section+i-var2stepcount-1)->y4;
-
- }
- printf("."); /* The it hasn't crashed indicator */
- }
- printf("\nSorting...");
- qsort(section,i,sizeof(struct sectiontype),(function)sectioncmp);
-
- printf("\done");
- entergraphics();
- i-=edgecount; /* Subtract the edges out */
- drawaxes(BACK); /* Draw back part of axes */
- plotsections(section,i);
- drawaxes(FRONT); /* And plot those sections */
- farfree(section);
- return 1;
- }
-
- void realscale(float *xx,float *yy,float *zz) {
- float x,y,z,dist;
-
- x=(*xx/xrange)-xmin/xrange/2-xmax/xrange/2;
- y=(*yy/yrange)-ymin/yrange/2-ymax/yrange/2;
- z=(*zz/zrange)-zmin/zrange/2-zmax/zrange/2;
- *zz=(x*cosspin-y*sinspin)*costip-z*sintip;
- if (distance==0.0) dist=1;
- else dist=distance+0.5-*zz;
- *xx=(y*cosspin+x*sinspin)*aspect/dist;
- *yy=(z*costip+(x*cosspin-y*sinspin)*sintip)/dist;
- }
-
-
- /* Compare to sections for qsort() */
-
- int sectioncmp(struct sectiontype *a,struct sectiontype *b)
- {
- if (a->x < b->x) return(-1);
- if (a->x == b->x) return(0);
- return(1);
- }
-
-
- void plotsections(struct sectiontype *section,int count) /* Plot count sections */
- {
- int i;
- for(i=0;i<count;i++)
- fill((section+i)->x1,(section+i)->y1,(section+i)->x2,(section+i)->y2,
- (section+i)->x3,(section+i)->y3,(section+i)->x4,(section+i)->y4);
-
- }
-
- void scale(int *xint,int *yint,float x,float y,float z) {
- realscale(&x,&y,&z);
- *xint=round(addx+multx*x);
- *yint=round(addy+multy*y);
- }
-
-
- void line3d(float a,float b,float c,float d,float e,float f) {
- int x1,y1,x2,y2;
-
- scale(&x1,&y1,a,b,c);
- scale(&x2,&y2,d,e,f);
- drawline(x1,y1,x2,y2);
- }
-
- /* Determine scaling constants */
-
-
- void calcscale(float xmin,float ymin,float zmin,float xmax,float ymax,float zmax)
- {
- float xs[2],ys[2],zs[2],yb=-1e37,ym=1e37,xm=1e37,xb=-1e37;
- char i,j,k;
-
- multx=1;
- addx=0;
- multy=1;
- addy=0;
- xs[0]=xmin;
- xs[1]=xmax;
- ys[0]=ymin;
- ys[1]=ymax;
- zs[0]=zmin;
- zs[1]=zmax;
- for(i=0;i<2;i++)
- for(j=0;j<2;j++)
- for(k=0;k<2;k++){
- xmin=xs[i];
- ymin=ys[j];
- zmin=zs[k];
- realscale(&xmin,&ymin,&zmin);
- if (xmin>xb) xb=xmin;
- else if (xmin<xm) xm=xmin;
- if (ymin>yb) yb=ymin;
- else if (ymin<ym) ym=ymin;
- }
- multx=((float)maxx)/(xb-xm);
- multy=((float)maxy)/(yb-ym);
- if (multx>multy) multx=multy; else multy=multx;
- multy=-multy;
- addx=-xm*multx+((float)maxx-multx*(xb-xm))/2;
- addy=(float)maxy-ym*multy-((float)maxy+multy*(yb-ym))/2;
- }
-
-
- static int faces[6][3]={{0,0,-1},{-1,0,0},{0,1,0},{1,0,0},{0,-1,0},{0,0,1}};
- static int edges[12][8]={
- {0,1,-1,-1,-1,-1,1,-1},
- {0,2,-1,1,-1,1,1,-1},
- {0,3,1,-1,-1,1,1,-1},
- {0,4,-1,-1,-1,1,-1,-1},
- {4,1,-1,-1,-1,-1,-1,1},
- {1,2,-1,1,-1,-1,1,1},
- {2,3,1,1,-1,1,1,1},
- {3,4,1,-1,-1,1,-1,1},
- {5,1,-1,-1,1,-1, 1,1},
- {5,2,-1, 1,1, 1, 1,1},
- {5,3, 1,-1,1, 1, 1,1},
- {5,4,-1,-1,1, 1,-1,1}};
-
-
- void drawaxes(char flag) /* Draw the axes */
- {
- int i;
- for(i=0;i<12;i++)
- if ((visible(edges[i][0]) && visible(edges[i][1]))==flag)
- line3d(FIX(edges[i][2],xmin,xmax), FIX(edges[i][3],ymin,ymax),
- FIX(edges[i][4],zmin,zmax), FIX(edges[i][5],xmin,xmax),
- FIX(edges[i][6],ymin,ymax), FIX(edges[i][7],zmin,zmax));
- }
-
-
- int visible(int i) /* determine if a face of the coordinate cube is visible */
- {
- return(faces[i][2] * sintip-(faces[i][0]*cosspin-faces[i][1]*sinspin)*costip<0);
- }
-
-
- SHAR_EOF
- fi
- if test -f 'plot3d.c'
- then
- echo shar: "will not over-write existing file 'plot3d.c'"
- else
- cat << \SHAR_EOF > 'plot3d.c'
- /*
-
- Plot3d -- plot3d.c, the main program
-
- By Adrian Mariano -- adrian@milton.u.washington.edu
-
-
- Copyright (c) 1991 by Adrian Mariano
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- */
-
- #include "plot3d.h"
- #include <string.h>
-
- extern unsigned _stklen = 32000;/* stack space to make qsort happy */
-
- /* status variables */
- char stop;
-
-
- void terminate(void)
- {
- backtotext();
- exit(0);
- }
-
-
- term fstack[maxffs + 1][100]; /* function stack for ff evaluation */
-
-
- typedef struct {
- float v1start, v1end, v2start, v2end;
- char *name;
- } bound;
-
- bound *currentbound;
-
-
- /* Functions to be passed to plot3d() for different plot types */
-
- void sphererho(float *x, float *y, float *z, float rho, float phi, float theta);
- void spherephi(float *x, float *y, float *z, float phi, float rho, float theta);
- void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho);
- void cartz(float *x, float *y, float *z, float zval, float xval, float yval);
- void cartx(float *x, float *y, float *z, float xval, float yval, float zval);
- void carty(float *x, float *y, float *z, float yval, float xval, float zval);
- void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta);
- void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval);
- void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval);
- void parametric(float *x, float *y, float *z, float dummy, float u, float v);
-
- bound sphererho_bound = {0, M_PI, 0, PI2, "sphererho"};
- bound spherephi_bound = {0, 3, 0, PI2, "spherephi"};
- bound spheretheta_bound = {0, M_PI, 0, 3, "spheretheta"};
-
- bound cartz_bound = {-3, 3, -3, 3, "cartz"};
- bound cartx_bound = {-3, 3, -3, 3, "cartx"};
- bound carty_bound = {-3, 3, -3, 3, "carty"};
-
- bound cylinderz_bound = {0, 3, 0, PI2, "cylinderz"};
- bound cylinderr_bound = {0, PI2, -3, 3, "cylinderr"};
- bound cylindertheta_bound = {0, 3, -3, 3, "cylindertheta"};
-
- char *xstr = "x";
- char *ystr = "y";
- char *zstr = "z";
- char *thetastr = "theta";
- char *rhostr = "rho";
- char *phistr = "phi";
- char *rstr = "r";
-
- char *var1str;
- char *var2str;
-
-
- void (*plottype) (float *, float *, float *, float, float, float);
-
-
- struct {
- char *st, *en;
- } replaces[] = {
- {"sinh", "sh"}, {"cosh", "ch"}, {"tanh", "th"},{"sin", "s"},
- {"cos", "c"}, {"arc", "A"}, {"ln", "n"}, {"log", "l"},{"abs","a"}
- };
-
-
-
- void setbounds(bound * newbound)
- {
- var1start = newbound->v1start;
- var2start = newbound->v2start;
- var1end = newbound->v1end;
- var2end = newbound->v2end;
- currentbound = newbound;
- }
-
- void substitute(char *str, char *start, char *end)
- {
- while (str = strstr(str, start)) {
- strnset(str, ' ', strlen(start));
- strncpy(str, end, strlen(end));
- }
- }
-
-
-
- void fixfun(char *fun)
- {
- int i;
- substitute(fun, var1str, "X");
- substitute(fun, var2str, "Y");
- substitute(fun, "X", "x");
- substitute(fun, "Y", "y");
-
- for (i = 0; i < sizeof(replaces) / (2 * sizeof(char *)); i++)
- substitute(fun, replaces[i].st, replaces[i].en);
- }
-
-
- void doreplot()
- {
- if (plot3d(plottype)) {
- getch();
- backtotext();
- }
- }
-
-
- void doplot(char *params)
- {
- char *errmesg;
- int where;
- fixfun(params);
- if ((where = convert(params, &errmesg, 0)) == -1) {
- simplify(0);
- if (plot3d(plottype)) {;
- getch();
- backtotext();
- }
- } else {
- while (where--)
- putchar(' ');
- printf(" ^\n%s\n", errmesg);
- }
- }
-
-
- float getval(char *expr, float def)
- {
- int where;
- char *errmesg;
- if ((where = convert(expr, &errmesg, maxffs)) == -1)
- return ff(def, def, maxffs);
- else {
- while (where--)
- putchar(' ');
- printf(" ^\n%s\n", errmesg);
- return def;
- }
- }
-
-
- void dotype(char *newtype)
- {
- if (!strcmp(newtype, "cartx")) {
- plottype = cartx;
- setbounds(&cartx_bound);
-
- var1str = ystr;
- var2str = zstr;
- } else if (!strcmp(newtype, "carty")) {
- plottype = carty;
- setbounds(&carty_bound);
- var1str = xstr;
- var2str = zstr;
- } else if (!strcmp(newtype, "cartz")) {
- plottype = cartz;
- setbounds(&cartz_bound);
- var1str = xstr;
- var2str = ystr;
- } else if (!strcmp(newtype, "sphererho")) {
- plottype = sphererho;
- setbounds(&sphererho_bound);
- var1str = phistr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "spherephi")) {
- plottype = spherephi;
- setbounds(&spherephi_bound);
- var1str = rhostr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "spheretheta")) {
- plottype = spheretheta;
- setbounds(&spheretheta_bound);
- var1str = phistr;
- var2str = rhostr;
- } else if (!strcmp(newtype, "cylinderz")) {
- plottype = cylinderz;
- setbounds(&cylinderz_bound);
- var1str = rstr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "cylinderr")) {
- plottype = cylinderr;
- setbounds(&cylinderr_bound);
- var1str = thetastr;
- var2str = zstr;
- } else if (!strcmp(newtype, "cylindertheta")) {
- plottype = cylindertheta;
- setbounds(&cylindertheta_bound);
- var1str = rstr;
- var2str = zstr;
- } else
- printf("Unknown coordinate system: %s\n\n", newtype);
- }
-
-
- void doshow()
- {
- printf("Coordinate system: %s\n",currentbound->name);
- printf("%s range: [%.17g,%.17g]\n%s range: [%.17g,%.17g]\n",
- var1str, var1start, var1end, var2str, var2start, var2end);
- printf("X: [%.17g,%.17g]\nY: [%.17g,%.17g]\nZ: [%.17g,%.17g]\n",
- xmin, xmax, ymin, ymax, zmin, zmax);
- printf("%s steps: %d\t%s steps: %d\n", var1str,
- (int) var1stepcount, var2str, (int) var2stepcount);
- printf("Aspect: %.17g\tDistance: %.17g\n", aspect, distance);
- printf("Spin: %.17g \tTip: %.17g\n", spin, tip);
- }
-
- void dohelp()
- {
- printf(
- "Commands:\n\n"
- "plot <function> -- function is in terms of the current coordinate system\n"
- "replot -- plot the same function again.\n"
- "type <cartz|cartx|carty|sphererho|spheretheta|spherephi|cylinderz|\n"
- " cylindertheta|cylinderr> -- Selects coordinate system for plotting\n"
- " where the variable name specified (sphereRHO) is the dependent variable\n"
- "show -- displays current plotting parameters\n"
- "xmin, xmax, ymin, ymax, zmin, zmax <value> -- set region to display on screen\n"
- "%sstart, %send, %sstart, %send, %ssteps, %ssteps <value> --\n"
- " Set the range for the independent variables, and the number of steps at\n"
- " which to sample the function\n"
- "aspect <value> -- set aspect ratio of screen\n"
- "distance <value> -- set perspect distance, 0 for no perspective\n"
- "spin, tip <value> -- set view angle in degrees\n\n"
- "Functions supported:\n"
- " [arc]sin, [arc]cos, [arc]tan, [arc]sinh, [arc]cosh, [arc]tanh\n"
- " ln, log, abs\n",var1str,var1str,var2str,var2str,var1str,var2str);
- }
-
-
- #define IS(XX) (!strcmp(command,XX))
-
-
- void main()
- {
- char input[100], command[100], params[100];
- char xcount[15], ycount[15], xstart[15], xend[15], ystart[15], yend[15];
- initgraphics();
- plottype = cartz;
- setbounds(&cartz_bound);
- var1str = xstr;
- var2str = ystr;
- printf(" -- Plot3d Version 1.0 by Adrian Mariano --\n"
- " -- Type 'help' for help --\n");
- do {
- printf("> ");
- gets(input);
- *command = *params = 0;
- sscanf(input, "%s %[^\n\r]", command, params);
- /* printf("'%s' '%s'\n",command,params); */
- strcpy(xcount, var1str);
- strcat(xcount, "steps");
- strcpy(ycount, var2str);
- strcat(ycount, "steps");
- strcpy(xstart, var1str);
- strcat(xstart, "start");
- strcpy(ystart, var2str);
- strcat(ystart, "start");
- strcpy(xend, var1str);
- strcat(xend, "end");
- strcpy(yend, var2str);
- strcat(yend, "end");
- if IS ("quit") break;
- else if IS ("plot") doplot(params);
- else if IS ("type") dotype(params);
- else if IS ("show") doshow();
- else if IS ("help") dohelp();
- else if IS ("zmin") zmin = getval(params, zmin);
- else if IS ("zmax") zmax = getval(params, zmax);
- else if IS ("ymin") ymin = getval(params, ymin);
- else if IS ("xmin") xmin = getval(params, xmin);
- else if IS ("ymax") ymax = getval(params, ymax);
- else if IS ("xmax") xmax = getval(params, xmax);
- else if IS (xcount) var1stepcount = getval(params, var1stepcount);
- else if IS (ycount) var2stepcount = getval(params, var2stepcount);
- else if IS (xstart) {
- currentbound->v1start = getval(params, var1start);
- setbounds(currentbound);
- }
- else if IS (ystart) {
- currentbound->v2start = getval(params, var2start);
- setbounds(currentbound);
- }
- else if IS (xend) {
- currentbound->v1end = getval(params, var1end);
- setbounds(currentbound);
- }
- else if IS (yend) {
- currentbound->v2end = getval(params, var2end);
- setbounds(currentbound);
- }
- else if IS ("replot") doreplot();
- else if IS ("aspect") aspect = getval(params, aspect);
- else if IS ("tip") tip = getval(params, tip);
- else if IS ("spin") spin = getval(params, spin);
- else if IS ("distance") distance = getval(params, distance);
- else if (!*command);
- else
- printf("Unknown command: %s\n", command);
- } while (1);
- clrscr();
- }
-
-
- /* A transform function for sphere notation */
-
-
- void sphererho(float *x, float *y, float *z, float rho, float phi, float theta)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
- void spherephi(float *x, float *y, float *z, float phi, float rho, float theta)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
- void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
-
- void cartz(float *x, float *y, float *z, float zval, float xval, float yval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
- void cartx(float *x, float *y, float *z, float xval, float yval, float zval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
- void carty(float *x, float *y, float *z, float yval, float xval, float zval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
-
- void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
- void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
-
- void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
-
- #pragma argsused
-
- void parametric(float *x, float *y, float *z, float dummy, float u, float v)
- {
- /* *x =1.7*cos(2*PI*u); y =1.7*sin(2*PI*u); z =v;
- *
- * x = 0.5*v*cos(2*PI*u); y = 0.5*v*sin(2*PI*u); z = 0.866*v;
- *
- * x = cos(2*PI*u)*sin(PI*v); y = sin(2*PI*u)*sin(PI*v); z = cos(PI*v);
- *
- * x = cos(PI*(2*u-1))*sin(PI*v); y = sin(PI*(2*u-1))*sin(PI*v); z = cos(PI*v);
- *
- * x = exp(u+v); y = exp(u*v); z = u*v*v;
- *
- * x = -v + 1; y = u - v; z = v; */
- float a = 2.0;
- float b = 0.8;
- *x = (a + b * cos(u)) * cos(v);
- *y = (a + b * cos(u)) * sin(v);
- *z = b * sin(u);
- }
- SHAR_EOF
- fi
- if test -f 'plot3d.h'
- then
- echo shar: "will not over-write existing file 'plot3d.h'"
- else
- cat << \SHAR_EOF > 'plot3d.h'
- /* header files */
- #include <conio.h>
- #include <dos.h>
- #include <stdio.h>
- #include <math.h>
- #include <alloc.h>
- #include <stdlib.h>
- #include <values.h>
-
- /* constants */
- #define maxffs 3
- #define PI2 6.28318530
-
- /* macros */
- #define range(min,value,max) (((min) <= (value)) && ((value) <= (max)))
-
- /* typedefs */
- typedef struct {
- char operator;
- double operand;
- } term;
-
-
- extern char ferr;
- extern term fstack[maxffs+1][100]; /* function stack for ff evaluation */
- extern int maxx,maxy,mode;
-
-
- extern float xmin; /* Dimensions of display area */
- extern float xmax;
- extern float ymin;
- extern float ymax;
- extern float zmin;
- extern float zmax;
-
- extern float aspect; /* Aspect ratio */
- extern float distance; /* Perspective distance */
- extern float tip; /* Rotation around y axis */
- extern float spin; /* Rotation around z axis */
-
- extern float var1start;
- extern float var2start;
- extern float var1end;
- extern float var2end;
-
- extern long var1stepcount; /* Number of steps over var 1 */
- extern long var2stepcount; /* Number of steps over var 2 */
-
- extern double ff(double arg1,double arg2, char stackno); /* function evaluator */
- extern int plot3d(void (*transform)(float *,float *,float *,float,float,float));
- extern void backtotext();
- extern void entergraphics();
- extern void initgraphics();
- extern void fill(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
- extern void drawline(int x1,int x2,int x3,int x4);
-
-
-
- SHAR_EOF
- fi
- if test -f 'readme'
- then
- echo shar: "will not over-write existing file 'readme'"
- else
- cat << \SHAR_EOF > 'readme'
- Plot3d
- by Adrian Mariano
- and Karl Crary
-
- Copyright 1991 by Adrian Mariano
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- Please send any comments, patches, or improvements to me at:
-
- adrian@milton.u.washington.edu
-
- Plot3d is a program for plotting 3 dimensional surfaces specified via one of
- the three standard coordinate systems.
-
- It uses a command driven interface with the following commands:
-
- type <type><dependent var>
-
- Selects coordinate system for plotting. The three available coordinate
- systems are: cartesian, a right handed orthoginal coordinate system with
- x, y and z as the variables; cylindrical, polar coordinate system with r
- the orthogonal distance from the z axis, theta the angle around the z
- axis, and z the distance along the z axis; and spherical, where rho is
- the distance from the origin, theta is the angle around the z axis, and
- phi is the angle between the z axis and the point.
-
- The <type> above should be one of cart, cylinder, or sphere.
-
- The dependent variable is the one which depends on the other two. It
- should be specified immediately after the type (without spaces).
-
- The default is cartz, which allows you to plot surfaces of the form
- z=f(x,y).
-
- To plot phi=f(rho, theta) in spherical coordinates, use the command
- 'type spherephi'
-
- plot <function>
-
- Plots the function with the current settings. The function should be
- specified WITHOUT an equals sign.
-
- So x^2+y^2 is ok. z=x^2+y^2 is not ok.
-
- Functions use the standard operations, +, -, /, *, and ^ (for exponents).
-
- e give 2.71828..., and pi produces the value pi.
-
- The '*' for multiplication may be omitted.
-
- The following functions are supported:
- [arc]sin, [arc]cos, [arc]tan, [arc]sinh, [arc]cosh, [arc]tanh
- ln, log, abs
-
- replot
-
- plots the same function again with the current settings (which may be
- different from when the function was last plotted).
-
- show
-
- displays current plotting parameters
-
- xmin, xmax, ymin, ymax, zmin, zmax <number>
-
- set the region to display on screen.
-
- <var>start, <var>end, <var>steps
-
- The program maintains separate values for the ranges over when the
- independent variables should vary, and the number of steps to take over
- this range for each coordinate system. You can set these values for the
- current coordinate system only by using these commands, where <var> is
- the variable you want to affect.
-
- aspect <number>
-
- Set aspect ratio of your monitor
-
- distance <number>
-
- Set perspective distance from image. Use 0 for no perspective. Distance
- is measured in multiples of the image depth (direction in the dimension
- perpendicular to your monitor).
-
- spin, tip <number>
-
- Set view angle in degrees. Spin rotates the image around the z axis, tip
- rotates the image around the y axis.
-
-
-
- LIMITATIONS
-
- Selecting more than about 55 x 55 resolution results in weird behavior for
- reasons I don't understand.
-
- EXAMPLES
-
- Here is an example session that produces a few interesting graphs:
-
- plot sin(x)
- plot sin(y)
- plot sin(x)*sin(y)
- type cylinderr
- plot 2.5
- plot sin(2z)
- plot sin(3z)+.5
- type sphererho
- plot 2.5sin(3theta)
- thetasteps 50
- phisteps 50
- replot
-
-
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-